﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using Hardcodet.Wpf.TaskbarNotification;
using Microsoft.VisualBasic;

namespace HostEdit
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {


        const String InitialHost = "Initial Host";


        IndexedObservableCollection<Hosts, String> ListeHosts = new IndexedObservableCollection<Hosts, string>(c => c.Name);
        
        public Hosts ContextHosts { get; set; }
        String path = Environment.CurrentDirectory + @"\Models.xml";
        string rep;
        System.IO.FileSystemWatcher Watcher;

        public MainWindow()
        {

            InitializeComponent();
            taskicon.DoubleClick += taskicon_DoubleClick;
            string root = Environment.GetFolderPath(Environment.SpecialFolder.Windows, Environment.SpecialFolderOption.None);
            rep = root + @"\System32\drivers\etc\hosts";
            this.ShowInTaskbar = false;
            ContextHosts = new Hosts();

          
            //taskicon
            
            //path = @"C:\statsql\toto.xml";

            if (new FileInfo(path).Exists)
            {
                List<Entries> l = null;
                l = l.LoadXml(path);

                foreach (Entries j in l)
                {
                    Hosts h = new Hosts();
                    h.Load(j);
                    AddHost(h);
                }
                
                
            }

            LstListeContext.ItemsSource = ListeHosts;

            // charge le Host
            LoadHosts();

            this.Visibility = System.Windows.Visibility.Collapsed;

            // Watch the Host file
            System.Threading.Thread t = new System.Threading.Thread(Watcher_Changed);
            t.Start();

        }

        void taskicon_DoubleClick(object sender, EventArgs e)
        {
            this.Visibility = System.Windows.Visibility.Visible;

        }


        bool exit = false;
        void Watcher_Changed()
        {
            
            FileInfo f = new FileInfo(rep);
            DateTime d = f.LastWriteTime;
            

            while (!exit)
            {
            
                f = new FileInfo(rep);
                if( f.LastWriteTime > d)
                {
                    d = f.LastWriteTime;
                    System.Threading.Thread t = new System.Threading.Thread(ShowUpdateBalloon);
                    t.Start();
                }            
                System.Threading.Thread.Sleep(500);
            }
        }


        void ShowUpdateBalloon()
        {
            string title = "Update";
            string text = "\nThe Host file has been updated        \n\n ";
            taskicon.ShowBalloonTip(title, text, BalloonIcon.Info);
            System.Threading.Thread.Sleep(8000);
            taskicon.HideBalloonTip();
        }


        public void LoadHosts()
        {

            Hosts CurrentHosts = new Hosts();

            System.IO.StreamReader j = new System.IO.StreamReader(rep);
            String o = j.ReadToEnd();
            j.Close();

            Regex Reg = new Regex(@"#*\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|::1)+\s*[\w_\.-]*");
            int Ind = 0;
            foreach (var i in Reg.Matches(o))
            {

                String Host = String.Empty;
                Match k = i as Match;

                if (Ind == 0)
                    Ind = k.Index - 1;

                String Ip = String.Empty;

                String[] l = k.Value.Replace(" ", "\t").Split('\t');

                bool Active = true;

                foreach (String m in l)
                {



                    if (String.IsNullOrEmpty(m.Trim())) continue;
                    if (String.IsNullOrEmpty(Ip))
                    {

                        if (m.StartsWith("#"))
                        {
                            Active = false;
                            continue;
                        }


                        Ip = m;
                        continue;
                    }

                    if (String.IsNullOrEmpty(Host))
                    {

                        Host = m.Trim().ToLower();

                        continue;
                    }

                }

                if (!CurrentHosts.Contains(Host))
                    CurrentHosts.Add(new Host { Name = Host });

                Host h = CurrentHosts.Get(Host);
                if (!h.Address.Contains(Ip))
                    h.Address.Add(new Adress { Value = Ip, Active = Active, Host = h });

            }

            // Récup. l'entete
            ExecuteClass.entete = o.Substring(0, Ind);
            if (!ExecuteClass.entete.Contains("AutoGenerated with Host Manager"))
                ExecuteClass.entete += @"\n# AutoGenerated with Host Manager";

            CurrentHosts.Name = String.Empty;

            if (ListeHosts.Count() != 0)
            {
                // test si Présent dans La liste
                String k1 = CurrentHosts.Save().SerializeXml().Replace(" ", "").ToLower();
                foreach (Hosts i in ListeHosts)
                {
                    String name = i.Name;
                    i.Name = String.Empty;
                    String k2 = i.Save().SerializeXml().Replace(" ", "").ToLower();
                    i.Name = name;
                    if (k1 == k2)
                    {
                        LstListeContext.SelectedItem = i;
                        return;
                    }
                }
            }

            CurrentHosts.Name = InitialHost;
            AddHost(CurrentHosts);
            LstListeContext.SelectedItem = CurrentHosts;

        }

        private void AddHost(Hosts CurrentHosts)
        {
            ListeHosts.Add(CurrentHosts);
            MenuItem menu = new MenuItem() { Header = CurrentHosts.Name, Command = new CommandMenuItem(), CommandParameter = CurrentHosts };
            taskicon.ContextMenu.Items.Add(menu);
        }


        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            Adress a = (sender as CheckBox).Tag as Adress;
            foreach (Adress i in a.Host.Address)
                if (i != a)
                    i.Active = false;
        }

        #region  Host

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {

            string i = Interaction.InputBox("Saisissez le nom du host", "", "");
            i = i.Trim().ToLower();
            if (!String.IsNullOrEmpty(i))
            {
                if (!ContextHosts.Contains(i))
                {
                    Host h = new Host() { Name = i };
                    ContextHosts.Add(h);
                    LstHost.SelectedItem = h;
                }
            }
        }


        /// <summary>
        /// Update Host
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            var ii = ((sender as Button).Tag as Host);
            string i = Interaction.InputBox("Saisissez le nom du host", ii.Name, ii.Name);
            if (!String.IsNullOrEmpty(i))
                ii.Name = i;
        }


        /// <summary>
        /// Delete Host
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_5(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show("êtes vous sûres de vouloir éffacer ce host ?", "Suppression", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes) == MessageBoxResult.Yes)
            {
                Host Host = (sender as Button).Tag as Host;
                ContextHosts.Remove(Host);
            }
        }


        /// <summary>
        /// Write the Host
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {

            ExecuteClass.WriteHost(ContextHosts);

        }


        #endregion

        #region IP


        /// <summary>
        /// Update IP
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_4(object sender, RoutedEventArgs e)
        {

            WriteIp iii = new WriteIp();
    
            var ii = ((sender as Button).Tag as Adress);
            iii.Retour = ii.Value;

            iii.ShowDialog();

            if (!String.IsNullOrEmpty(iii.Retour))
                ii.Value = iii.Retour;

            GC.SuppressFinalize(iii);

        }


        /// <summary>
        /// Add Ip
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_6(object sender, RoutedEventArgs e)
        {

            WriteIp iii = new WriteIp();
            
            iii.ShowDialog();


            if (!String.IsNullOrEmpty(iii.Retour))
            {
                Host Host = (sender as Button).Tag as Host;
                Host.Address.Add(new Adress() { Host = Host, Value = iii.Retour, Active = true });
            }

            GC.SuppressFinalize(iii);
            
        }


        /// <summary>
        /// Del IP
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_7(object sender, RoutedEventArgs e)
        {

            if (MessageBox.Show("êtes vous sûres de vouloir éffacer cette adresse IP?", "Suppression", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes) == MessageBoxResult.Yes)
            {
                Adress Add = (sender as Button).Tag as Adress;
                Add.Host.Address.Remove(Add);
            }

        }

        #endregion
        

        /// <summary>
        /// Save the Models
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_2(object sender, RoutedEventArgs e)
        {

            Save();

        }

        private void Save()
        {
            List<Entries> l = new List<Entries>();

            foreach (Hosts i in ListeHosts)
                if (i.Name != InitialHost)
                    l.Add(i.Save());

            if (l.Count > 0)
                l.SaveXml(path);

        }


        private void LstListeContext_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

            ContextHosts = (sender as ComboBox).SelectedItem as Hosts;
            this.DataContext = ContextHosts;
        }


        /// <summary>
        ///  Show
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.Visibility = System.Windows.Visibility.Visible;
        }


        private bool TestClose = false;
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (TestClose) return;
            e.Cancel = true;
            this.Visibility = System.Windows.Visibility.Hidden;            
        }


        private void Window_StateChanged(object sender, EventArgs e)
        {
            if (this.WindowState == System.Windows.WindowState.Minimized)
            {
                this.Visibility = System.Windows.Visibility.Hidden;
                this.WindowState = System.Windows.WindowState.Normal;
            }
        }


        private void Window_Closed(object sender, EventArgs e)
        {
            taskicon.Visibility = System.Windows.Visibility.Hidden;
        }


        /// <summary>
        /// Close
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuItem_Click_1(object sender, RoutedEventArgs e)
        {
            TestClose = true;
            exit = true;
            Button_Click(null, null);
            Save();
            this.Close();
            //GC.SuppressFinalize(this);
        }


        private void Window_Activated(object sender, EventArgs e)
        {
            if (TestClose)
            {
                this.Focus();
                TestClose = false;
                return;
            }
            this.Visibility = System.Windows.Visibility.Collapsed;
        }


        /// <summary>
        /// Add new Model
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_8(object sender, RoutedEventArgs e)
        {

            string i = Interaction.InputBox("Saisissez le nom du model", "", "");
            i = i.Trim().ToLower();
            if (!String.IsNullOrEmpty(i))
            {
                if (!ContextHosts.Contains(i))
                {
                    Hosts h = new Hosts() { Name = i };

                    

                    Host h2 = new Host() { Name = "localhost" };
                    h2.Address.Add(new Adress() { Active = true, Host = h2, Value = "::1" });
                    h.Add(h2);
                    AddHost(h);
                    LstListeContext.SelectedItem = h;
                }
            }

            
        }
        
        /// <summary>
        /// Delete model
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_9(object sender, RoutedEventArgs e)
        {

            if (ContextHosts.Name == InitialHost)
            {
                MessageBox.Show("Vous ne pouvez pas éffacer le model de base.", "Suppression", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
                return;
            }

            if (MessageBox.Show("êtes vous sûres de vouloir éffacer ce model ?", "Suppression", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes) == MessageBoxResult.Yes)
            {

                MenuItem ii1 = null;
                foreach (System.Windows.Controls.Control item in taskicon.ContextMenu.Items)
                    if (item.Tag == ContextHosts)
                    {
                        ii1 = (MenuItem)item;
                        break;
                    }

                
                taskicon.ContextMenu.Items.Remove(ii1);

                ListeHosts.Remove(ContextHosts);
                ContextHosts = ListeHosts.Get(0);
                LstListeContext.SelectedItem = ContextHosts;
            }

        }


        /// <summary>
        /// Copy profil
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_10(object sender, RoutedEventArgs e)
        {

            string i = Interaction.InputBox("Saisissez le nom du model", "", "");
            i = i.Trim().ToLower();
            if (!String.IsNullOrEmpty(i))
            {
                if (!ContextHosts.Contains(i))
                {
                    Hosts h = new Hosts() { Name = i };

                    foreach (var m in ContextHosts)
                    {

                        h.Add(m.Copy());          
                    }

                    AddHost(h);
                    LstListeContext.SelectedItem = h;
                }
            }

        }

        /// <summary>
        /// Quitter
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click_12(object sender, RoutedEventArgs e)
        {
            MenuItem_Click_1(null, null);
        }

        //private void CheckBox_Checked_1(object sender, RoutedEventArgs e)
        //{
            //RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
            //if ((bool)WindowsStart.IsChecked)
            //    key.SetValue("HostEdit", Environment.CommandLine);
            //else
            //    key.SetValue("HostEdit", String.Empty);
        //}

        #region JumpList

    //            private void AddTask(object sender, RoutedEventArgs e)
    //    {
    //        // Configure a new JumpTask.
    //        JumpTask jumpTask1 = new JumpTask();
    //        // Get the path to Calculator and set the JumpTask properties.
    //        jumpTask1.ApplicationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "calc.exe");
    //        jumpTask1.IconResourcePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "calc.exe");
    //        jumpTask1.Title = "Calculator";
    //        jumpTask1.Description = "Open Calculator.";
    //        jumpTask1.CustomCategory = "User Added Tasks";
    //        // Get the JumpList from the application and update it.
    //        JumpList jumpList1 = JumpList.GetJumpList(App.Current);
    //        jumpList1.JumpItems.Add(jumpTask1);
    //        JumpList.AddToRecentCategory(jumpTask1);
    //        jumpList1.Apply();
    //    }
    //    private void ClearJumpList(object sender, RoutedEventArgs e)
    //    {
    //        JumpList jumpList1 = JumpList.GetJumpList(App.Current);
    //        jumpList1.JumpItems.Clear();
    //        jumpList1.Apply();
    //    }
    //    private void SetNewJumpList(object sender, RoutedEventArgs e)
    //    {
    //        //Configure a new JumpTask
    //        JumpTask jumpTask1 = new JumpTask();
    //        // Get the path to WordPad and set the JumpTask properties.
    //        jumpTask1.ApplicationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "write.exe");
    //        jumpTask1.IconResourcePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "write.exe");
    //        jumpTask1.Title = "WordPad";
    //        jumpTask1.Description = "Open WordPad.";
    //        jumpTask1.CustomCategory = "Jump List 2";
    //        // Create and set the new JumpList.
    //        JumpList jumpList2 = new JumpList();
    //        jumpList2.JumpItems.Add(jumpTask1);
    //        JumpList.SetJumpList(App.Current, jumpList2);
    //    }
    //}

        #endregion


    }
}
